package com.lc.common.component;

import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 服务内鉴权
 *
 * @author LingChou
 */
@Configuration
@Order(1)
@Log4j2
public class AuthenticationFilter extends OncePerRequestFilter {

    static List<String> endWithFilterList = new ArrayList<>();

    static {
        // swagger
        endWithFilterList.add("/api-docs-ext");
        endWithFilterList.add("/api-docs");
        endWithFilterList.add("/swagger-resources/configuration/ui");
        endWithFilterList.add("/swagger-resources");
        //druid
        endWithFilterList.add("/druid/submitLogin");

        endWithFilterList.add(".html");
        endWithFilterList.add(".js");
        endWithFilterList.add(".css");
        endWithFilterList.add(".ico");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String addr = request.getRemoteAddr();
        String host = request.getRemoteHost();
        int port = request.getRemotePort();
        String requestURI = request.getRequestURI();
        String loginInfoHeader = request.getHeader("login-info");
        String sAHeader = request.getHeader("S_A");
        for (String path : endWithFilterList) {
            if (request.getRequestURI().endsWith(path)) {
                log.info("ApiPass:addr:{},host:{},port:{},requestURI:{}", addr, host, port, requestURI);
                filterChain.doFilter(request, response);
                return;
            }
        }
        if (loginInfoHeader != null || sAHeader != null) {
            log.info("ApiPass:addr:{},host:{},port:{},requestURI:{},header:{}",
                    addr, host, port, requestURI, URLDecoder.decode(sAHeader == null ? loginInfoHeader : sAHeader, String.valueOf(StandardCharsets.UTF_8)));
            filterChain.doFilter(request, response);
            return;
        }
        log.info("ApiReject:addr:{},host:{},port:{},requestURI:{}", addr, host, port, requestURI);
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
    }
}